package pl.cezary.butler.walili.server;

import pl.cezary.butler.walili.common.IServerFacadeRemote;
import pl.cezary.butler.walili.common.User;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import pl.cezary.butler.walili.server.db.Database;
import pl.cezary.butler.walili.server.db.tasks.DoesUserExistsTask;
import pl.cezary.butler.walili.server.db.tasks.DoesUserExistsByLoginTask;
import pl.cezary.butler.walili.server.db.tasks.CreateUserTask;
import pl.cezary.butler.walili.server.db.utils.StorageBD;

/**
 * 
 * @author Cezary Butler
 */
public class LoginFacadeRMI extends AbstractLoginFacade {

    private static final Logger log = Logger.getLogger("FasadaSerweraLogin");    
    
    private Database bazaDanych;

    public LoginFacadeRMI() {
        bazaDanych = StorageBD.getBD(Server.MAIN_DB);
    }


    @Override
    public IServerFacadeRemote zaloguj(User user) {  // TODO obsluga bledow: poprawic logi, zwrocic null w przypadku nieobslugiwalnego bledu
        IServerFacadeRemote fasadaStub = null;
        try {
            // TODO obsluga bledow
            UserId uid = UserId.getUser(user);
            if (uid != null) {
                fasadaStub = (IServerFacadeRemote) UnicastRemoteObject.exportObject(new ServerRMIUserFacade(uid));
                try {
                    Server.getRegistry().bind(uid.toString(), fasadaStub);
                } catch (AlreadyBoundException bound) {
                    log.log(Level.INFO, "Uzytkownik {0} jest juz zalogowany, zwracam zarejestrowana fasade", user);
                    try {
                        fasadaStub = (IServerFacadeRemote) Server.getRegistry().lookup(uid.toString());
                    } catch (NotBoundException ex) {
                        log.log(Level.SEVERE, "Mimo zalogowania uzytkownika nie udalo sie pobrac fasady");
                        fasadaStub = null;
                    }
                }
            }
        } catch (AccessException ex) { // to nigdy nie powinno wystapis
            log.log(Level.SEVERE, "Brak dostępu (metoda prawdopodobnie wykonana na zdalnym hoście)", ex);
            fasadaStub = null;
        } catch (RemoteException ex) {
            log.log(Level.SEVERE, "Bład w obsludze rmi", ex);
            fasadaStub = null;
        }
        return fasadaStub;

    }
    
    @Override
    public List<String> zarejestruj(User user) {
        List<String> err = new LinkedList<String>();
        try {
            UserId uid = UserId.getUser(user);
            final String LOGIN = user.getLogin();
            final String HASLO = user.getHaslo();
            
            DoesUserExistsTask czyUser = new DoesUserExistsTask(user);
            //czyUser.setDataBase(bazaDanych); FIXME
            czyUser.execute();
            if (czyUser.getResults()) {
                return err;
            } else {
                DoesUserExistsByLoginTask czyUserOLoginie = new DoesUserExistsByLoginTask(LOGIN);
                //czyUserOLoginie.setDataBase(bazaDanych); FIXME
                czyUserOLoginie.execute();
                if (czyUserOLoginie.getResults()) {
                    err.add("U\u017cytkownik o loginie: " + LOGIN + " juz istnieje! Wybierz inny login");
                    return err;
                } else {
                    CreateUserTask dodajUsera = new CreateUserTask(user);
                    //dodajUsera.setDataBase(bazaDanych); FIXME
                    dodajUsera.execute();
                    DoesUserExistsTask czyUser2 = new DoesUserExistsTask(user);
                    //czyUser2.setDataBase(bazaDanych); FIXME
                    czyUser2.execute();
                    if (czyUser2.getResults()) {
                        return err;
                    } else {
                        err.add("Nie udalo si\u0119 doda\u0107 u\u017cytkownika. Prosz\u0119 spr\u00f3bowa\u0107 p\u00f3\u017aniej");
                        return err;
                    }
                }
            }
        } catch (SQLException ex) {
            log.log(Level.SEVERE, "Błąd podczas próby zarządzania użytkownikiem", ex);
            err.add("Nie udalo si\u0119 doda\u0107 u\u017cytkownika. Prosz\u0119 spr\u00f3bowa\u0107 p\u00f3\u017aniej");
        }
        return err;
    }

    @Override
    public boolean isCredentinalsNeccessary() throws RemoteException {
        return true;
    }
}

